// 用户管理

package basic

import (
	"api/common"
	"api/common/logger"
	"api/common/orm"
	"api/common/web"
	"api/models"
	"fmt"
	"net/http"
	"time"
)

// @TagName 用户管理
// @Controller UserController
type UserController struct{}

// @Title 用户列表数据
// @Route /user/list --> List
// @Method post
func (this *UserController) List(w http.ResponseWriter, r *http.Request) {
	defer web.PanicHandler(w, r)
	web.JsonCallBak(w, r, &models.User{})
}

// @Title 新增用户信息
// @Route /user/create --> Create
// @Method post
func (this *UserController) Create(w http.ResponseWriter, r *http.Request) {
	defer web.PanicHandler(w, r)
	web.CreateRecord(w, r, &models.User{})
}

// @Title 编辑用户信息
// @Route /user/edit --> Edit
// @Method post
func (this *UserController) Edit(w http.ResponseWriter, r *http.Request) {
	defer web.PanicHandler(w, r)
	web.EditRecord(w, r, &models.User{})
}

// @Title 删除用户信息
// @Route /user/delete --> Delete
// @Method post
func (this *UserController) Delete(w http.ResponseWriter, r *http.Request) {
	defer web.PanicHandler(w, r)
	web.DeleteCallBak(w, r, &models.User{})
}

// @Title 用户登录
// @Desc userName为用户名，passwd为用户密码md5加密值，返回登录状态，登录成功则返回用户可见菜单
// @Param {"userName":"admin","passwd":"e10adc3949ba59abbe56e057f20f883e"}
// @Route /user/login --> Login
// @Method post
func (this *UserController) Login(w http.ResponseWriter, r *http.Request) {
	defer web.PanicHandler(w, r)
	inputJson, msg := web.ExemptTokenCheckRequest(r)
	if msg != nil {
		web.ServeJSON(w, msg)
		return
	}

	userName := inputJson["userName"]
	passwd := inputJson["passwd"]
	//captcha := inputJson["captcha"]

	if userName == nil || userName == "" {
		web.ServeJSON(w, web.JsonMsg{false, "用户名不能为空", 1})
		return
	}
	if passwd == nil || passwd == "" {
		web.ServeJSON(w, web.JsonMsg{false, "密码不能为空", 1})
		return
	}

	isUserNameDanger := common.CheckSQLInject(common.ToStr(userName), true)
	isPasswdDanger := common.CheckSQLInject(common.ToStr(passwd), true)
	if isUserNameDanger || isPasswdDanger {
		web.ServeJSON(w, web.JsonMsg{false, "请勿尝试SQL注入！", 1})
		return
	}

	// 验证
	sql := "select u.id, u.`name`, u.user_name, u.phone, u.`status`, r.menus, r.res" +
		" from basic_user u left join basic_role r on u.roles = r.id" +
		" where u.user_name = ? and u.passwd = ?"
	type User struct {
		Id       uint32 `json:"id"`
		Name     string `json:"name"`
		UserName string `json:"userName"`
		Phone    string `json:"phone"`
		Status   bool   `json:"status"`
		Menus    string `json:"menus"`
		Res      string `json:"res"`
	}
	user := &User{}
	conn := orm.NewOrm()
	err := conn.Raw(sql, userName, passwd).QueryRow(user)
	if err != nil || user.UserName == "" {
		web.ServeJSON(w, web.JsonMsg{false, "用户名或密码错误", 1})
		return
	}
	if !user.Status {
		web.ServeJSON(w, web.JsonMsg{false, "用户已经停用", 1})
		return
	}

	// 生成菜单数据
	where := ""
	if user.Menus != "" {
		where = " where id in (" + user.Menus + ")"
	}
	sql = "select * from basic_menu" + where
	menuData := []models.Menu{}
	_, err = conn.Raw(sql).QueryRows(&menuData)
	if err != nil {
		logger.Error("查询菜单发生错误", err)
		web.ServeJSON(w, web.JsonMsg{false, "查询菜单发生错误" + err.Error(), 1})
		return
	}

	// 生成访问令牌
	token := common.RandStr(64, 1)
	key := fmt.Sprintf("admin_user_%d", user.Id)
	common.RedisClient.Set(key, string(token), time.Minute*common.Config.AdminTokenValidMinute)

	data := map[string]interface{}{}
	data["msg"] = "登录成功"
	data["success"] = true
	data["status"] = 0

	data["token"] = string(token)
	data["userId"] = user.Id

	data["phone"] = user.Phone
	data["name"] = user.Name
	data["userName"] = user.UserName

	data["menuData"] = menuData
	data["res"] = user.Res
	web.ServeJSON(w, data)
}

// @Title 修改密码
// @Desc 修改用户密码，oldPasswd 为原密码，newPasswd为新密码
// @Param {"userId":1,"token":"1","oldPasswd":"","newPasswd":""}
// @Route /user/changPasswd --> ChangPasswd
// @Method post
func (this *UserController) ChangPasswd(w http.ResponseWriter, r *http.Request) {
	defer web.PanicHandler(w, r)
	inputJson, msg := web.TokenCheckRequest(r)
	if msg != nil {
		web.ServeJSON(w, msg)
		return
	}

	userId := inputJson["userId"]
	oldPasswd := inputJson["oldPasswd"]
	newPasswd := inputJson["newPasswd"]

	conn := orm.NewOrm()
	currentPw := ""
	sql := "select passwd from basic_user where id=?"
	err := conn.Raw(sql, userId).QueryRow(&currentPw)
	if err != nil {
		logger.Error("查询系统管理员密码发生错误", err)
		web.ServeJSON(w, web.JsonMsg{false, "查询系统管理员密码发生错误", 1})
		return
	}
	if common.ToStr(oldPasswd) != currentPw {
		web.ServeJSON(w, web.JsonMsg{false, "原密码错误", 1})
		return
	}

	sql = "update basic_user set passwd=? where id=?"
	_, err = conn.Raw(sql, newPasswd, userId).Exec()
	if err != nil {
		logger.Error("更新系统管理员密码发生错误", err)
		web.ServeJSON(w, web.JsonMsg{false, "更新系统管理员密码发生错误", 1})
		return
	}

	web.ServeJSON(w, web.JsonMsg{true, "系统管理员密码修改成功", 0})
}

// @Title 系部列表数据
// @Route /user/dept --> Dept
// @Method post
func (this *UserController) Dept(w http.ResponseWriter, r *http.Request) {
	defer web.PanicHandler(w, r)
	inputJson, msg := web.TokenCheckRequest(r)
	if msg != nil {
		web.ServeJSON(w, msg)
		return
	}

	web.JsonCallBakFilter(w, inputJson, &models.Special{}, "", "pid=0", "")
}
